#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using TTXNA.src.Engine.World;
using TTXNA.src.Engine.Graphics;
using TTXNA.src.Engine.GUI;
using TTXNA.src.Engine.Input;
#endregion

namespace TTXNA
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class TTXNAGame : Microsoft.Xna.Framework.Game
    {
        public static GraphicsDeviceManager graphics;
        public static ContentManager content;

        //private TTScene gameScene;
        private TTCamera camera;
        private GUIManager gameGUI;

        public static TTWorld graphicsWorld;
        private static GameWorld gameWorld;

        private static float heightScale = 4;
        

        private static InputHandler input;

        private List<double> frameTimes = new List<double>();

        

        int frames = 0;
        double drawMillis = 0;

        int updates = 0;
        double updateMillis = 0;


        public TTXNAGame()
        {
            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);
            
            graphics.SynchronizeWithVerticalRetrace = false;
            graphics.IsFullScreen = false;
            graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
            IsFixedTimeStep = false;            
        }

        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            //e.GraphicsDeviceInformation.Adapter = GraphicsAdapter.Adapters[1];

            if (graphics.IsFullScreen)
            {
                e.GraphicsDeviceInformation.PresentationParameters.BackBufferWidth = 1600;
                e.GraphicsDeviceInformation.PresentationParameters.BackBufferHeight = 1200;
            }
            else
            {
                e.GraphicsDeviceInformation.PresentationParameters.BackBufferWidth = 1280;
                e.GraphicsDeviceInformation.PresentationParameters.BackBufferHeight = 720;
            }
            e.GraphicsDeviceInformation.PresentationParameters.MultiSampleType = MultiSampleType.None;
            e.GraphicsDeviceInformation.PresentationParameters.PresentationInterval = PresentInterval.Immediate;            
        }

        protected override void Initialize()
        {
            input = new InputHandler(this);

            base.Initialize();
        }

        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {

            }

            camera = new TTCamera(graphics.GraphicsDevice.PresentationParameters.BackBufferWidth,
                                    graphics.GraphicsDevice.PresentationParameters.BackBufferHeight);

            PostGraphicsInitialize();
        }

        private void PostGraphicsInitialize()
        {
            graphicsWorld = new TTWorld();
            gameWorld = new GameWorld(this, 32, 32);
            gameGUI = new GUIManager();
        }

        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent)
            {
                content.Unload();
            }
        }

        protected override void Update(GameTime gameTime)
        {
            //updates++;
            //updateMillis += gameTime.ElapsedGameTime.TotalMilliseconds;

            //if (updateMillis > 1000)
            //{
            //    //Console.WriteLine("Updates: " + updates);
            //    updates = 0;
            //    updateMillis = 0;
            //}
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            input.Update(gameTime);

            graphicsWorld.Update(gameTime);
            gameWorld.Update(gameTime);
            

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.Black);

            //graphics.GraphicsDevice.RenderState.ScissorTestEnable = true;
            //graphics.GraphicsDevice.ScissorRectangle = new Rectangle(50, 50, 500, 500);
            
            graphicsWorld.Render(camera);

            base.Draw(gameTime);
        }

        public GUIManager GUI
        {
            get { return gameGUI; }
        }

        public TTCamera Camera
        {
            get { return camera; }
        }

        public static InputHandler Input
        {
            get { return input; }
        }

        public GraphicsDevice GraphicsDevice
        {
            get { return graphics.GraphicsDevice; }
        }

        public static GameWorld World
        {
            get { return gameWorld; }
        }

        public static float HeightScale
        {
            get { return heightScale; }
        }

        public Point Resolution
        {
            get
            {
                return new Point(graphics.GraphicsDevice.PresentationParameters.BackBufferWidth,
                                  graphics.GraphicsDevice.PresentationParameters.BackBufferHeight);
            }
        }
    }
}
